package br.unp.tasi.loja.repositorios.impl;

import br.unp.tasi.loja.entidades.Produto;
import br.unp.tasi.loja.repositorios.RepositorioProduto;

import java.util.List;

import javax.inject.Named;
import javax.persistence.Query;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Named("br.unp.tasi.loja.repositorios.RepositorioProduto")
public class RepositorioProdutoImpl extends RepositorioBasicolmpl implements RepositorioProduto {

  @Override
  public List<Produto> localizarOfertas() {
    return getEntityManager().createQuery("from Produto p "
            /* Melhora a performance da consulta,
            recuperando a categoria tambem. Retire o Join Fetch para ver a perda
            de performance. Ver http://blogs.sun.com/carolmcdonald/entry/jpa_performance_don_t_ignore */
            + "join fetch p.categoria "
            + "where p.emoferta=1 "
            + "order by p.nome").
            setMaxResults(9).
            getResultList();
  }

  @Override
  public List<Produto> localizarTodos() {
    return getEntityManager().createQuery("from Produto p "
            + "join fetch p.categoria "
            + "order by p.emoferta DESC, "
            + "p.categoria.nome, "
            + "p.nome").getResultList();
  }

  @Override
  public List<Produto> localizarOfertasPorCategoria(Long categoria) {
    return getEntityManager().createQuery(
            "from Produto p "
            + "join fetch p.categoria "
            + "where p.emoferta=1 and "
            + "p.categoria.id = :categoria_id "
            + "order by p.nome").
            setMaxResults(9).
            setParameter("categoria_id", categoria).
            getResultList();
  }

  @Override
  public List<Produto> localizarProdutosPor(String filtro, Long categoria) {
    if (categoria == 0) {
      String consultaParaQualquerCategoria = "from Produto p "
              + "join fetch p.categoria "
              + "where p.nome like :filtro "
              + "order by p.nome";

      return getEntityManager().createQuery(consultaParaQualquerCategoria).
              setParameter("filtro", "%" + filtro + "%").
              setMaxResults(9). /* Numero maximo de resultados */
              getResultList();

    } else {
      String consultaParaCategoriaEspecifica = "from Produto p "
              + "join fetch p.categoria "
              + "where p.nome like :filtro and "
              + "p.categoria.id = :categoria "
              + "order by p.nome";

      return getEntityManager().createQuery(consultaParaCategoriaEspecifica).
              setParameter("filtro", "%" + filtro + "%").
              setParameter("categoria", categoria).
              setMaxResults(9). /* Numero maximo de resultados */
              getResultList();
    }
  }

  @Override
  public Produto localizarPeloID(Long id) {
    return getEntityManager().find(Produto.class, id);
  }

  @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
  @Override
  public void apagarPeloID(Long id) {
    super.apagar(localizarPeloID(id));
  }

  @Override
  public Long tamanho() {
    Query query = getEntityManager().createQuery("SELECT COUNT(p.id) FROM Produto p");
    return (Long) query.getSingleResult();
  }
}
/*
http://blog.springsource.com/2007/11/14/annotated-web-mvc-controllers-in-spring-25/<br/>
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html<br/>
 */
